<template>
    <div>
        <el-input style="width: 200px; margin-right: 10px;" v-model="searchObj.username"
            placeholder="根据用户名查询"></el-input>
        <el-input style="width: 200px; margin-right: 10px;" v-model="searchObj.nickName"
            placeholder="根据昵称查询"></el-input>
        <el-button type="primary" icon="el-icon-search" @click="search">查询</el-button>
        <el-button @click="clear">清空</el-button>

        <div class="user-list">
            <el-button type="primary" icon="el-icon-plus" @click="addUser">添加</el-button>
            <el-button type="danger" icon="el-icon-delete" :disabled="userIdList.length<1"
                @click="deleteChecked">批量删除</el-button>
            <!-- 用户列表 -->
            <el-table :data="userList" empty-text="暂无数据" border stripe style="margin-top: 20px;" v-loading="listLoading"
                @selection-change="handleSelectionChange">
                <el-table-column type="selection" width="60" align="center"></el-table-column>
                <el-table-column label="序号" type="index" width="80" align="center"></el-table-column>
                <el-table-column label="用户名" prop="username" width="width"></el-table-column>
                <el-table-column label="用户昵称" prop="nickName" width="width"></el-table-column>
                <el-table-column label="权限列表" prop="roleName" width="width"></el-table-column>
                <el-table-column label="创建时间" prop="gmtCreate" width="width"></el-table-column>
                <el-table-column label="更新时间" prop="gmtModified" width="width"></el-table-column>
                <el-table-column label="操作" prop="prop" width="300" align="center">
                    <template slot-scope="{row,$index}">
                        <el-button type="info" icon="el-icon-user-solid" @click="assignRole(row)"></el-button>
                        <el-button type="primary" icon="el-icon-edit" @click="editUser(row)"></el-button>
                        <el-popconfirm :title="`确定删除${row.username}吗？`" @onConfirm="deleteUser(row)">
                            <el-button style="margin-left: 10px;" type="danger" slot="reference"
                                icon="el-icon-delete"></el-button>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 分页器 -->
            <!-- 
            current-page: 当前是第几页
            total: 一共有多少条数据需要展示
            page-size: 每一页需要展示多少条数据
            page-sizes: 设置每一页展示多少条数据
            pager-count: 连续的页码数
            layout: 设置分页器的布局| -> : 代表将箭头后的元素移动至页面最右端
            @current-change="handleCurrentChange" : 切换页码时触发
            @size-change="handleSizeChange" : 当前页面显示数据条数改变时触发
            @prev-click="handlePrevClick" : 点击上一页
            @next-click="handleNextClick" : 点击下一页
            -->
            <el-pagination background style="margin-top: 30px; text-align: left;" :current-page="page" :total="total"
                :page-size="limit" :page-sizes="[3,5,7]" :pager-count="7" layout="prev,pager,next,jumper,->,sizes,total"
                @current-change="handleCurrentChange" @size-change="handleSizeChange" @prev-click="handlePrevClick"
                @next-click="handleNextClick">
            </el-pagination>
        </div>

        <!-- 添加 | 修改用户弹框 -->
        <el-dialog :title="isAdd?'添加用户':'修改用户'" :visible.sync="addUserDialogVisible" width="50%">
            <span>
                <el-form :model="user" :rules="userRules" ref="ruleForm" label-width="80px">
                    <el-form-item label="用户名" prop="username">
                        <el-input placeholder="请输入用户名" v-model="user.username"></el-input>
                    </el-form-item>
                    <el-form-item label="用户昵称" prop="nickName">
                        <el-input placeholder="请输入用户昵称" v-model="user.nickName"></el-input>
                    </el-form-item>
                    <el-form-item label="用户密码" prop="password" v-if="isAdd">
                        <el-input placeholder="请输入用户密码" v-model="user.password"></el-input>
                    </el-form-item>
                </el-form>
            </span>
            <span slot="footer" class="dialog-footer">
                <el-button @click="addUserDialogVisible = false">取消</el-button>
                <el-button type="primary" @click="confirmAddOrAditUser">确定</el-button>
            </span>
        </el-dialog>

        <!-- 设置角色弹框 -->
        <el-dialog title="设置角色" :visible.sync="roleDialogVisible" width="50%">
            <span>
                <el-form :model="roleForm" label-width="80px">
                    <el-form-item label="用户名">
                        <el-input placeholder="请输入用户名" disabled v-model="roleForm.username"></el-input>
                    </el-form-item>
                    <el-form-item label="角色列表">
                        <el-checkbox :indeterminate="roleForm.isIndeterminate" v-model="roleForm.checkAll"
                            @change="handleCheckAllChange">全选</el-checkbox>
                        <div style="margin: 15px 0;"></div>
                        <el-checkbox-group v-model="roleForm.roleIdList" @change="handleCheckedRoleChange">
                            <el-checkbox v-for="role in roleForm.allRolesList" :label="role.id"
                                :key="role.id">{{role.roleName}}</el-checkbox>
                        </el-checkbox-group>
                    </el-form-item>
                </el-form>
            </span>
            <span slot="footer" class="dialog-footer">
                <el-button @click="roleDialogVisible = false">取消</el-button>
                <el-button type="primary" @click="confirmAssignRole">确定</el-button>
            </span>
        </el-dialog>
    </div>
</template>
<script>
    export default {
        name: "User",
        mounted() {
            this.getUserList()
        },
        data() {
            return {
                searchObj: { // 搜索的对象|携带给服务器的
                    username: '', // 用户名
                    nickName: '' // 昵称
                },
                total: 0, // 总共多少条数据
                page: 1, // 当前页码
                limit: 3, // 每页显示多少条数据
                userList: [], // 用户列表
                userIdList: [], // 用户id列表
                listLoading: false, // 用户列表加载动画
                addUserDialogVisible: false, // 添加用户弹框显示/隐藏
                roleDialogVisible: false, // 设置角色弹框
                isAdd: true, // 是否是添加用户弹框 | true：添加 / false：修改
                user: { // 收集添加用户的数据
                    username: '', // 用户名
                    nickName: '', // 用户昵称
                    password: '', // 用户密码
                },
                userRules: { // 添加|修改用户的表单验证规则
                    username: [
                        { required: true, message: '请输入用户名', trigger: 'change' },
                    ],
                    nickName: [
                        { required: false },
                    ],
                    password: [
                        { required: true, message: '请输入密码', trigger: 'change' },
                    ],
                },
                roleForm: { // 收集设置角色的数据
                    checkAll: false, // 是否全选
                    userId: 0, // 用户id
                    username: '111', // 用户名
                    allRolesList: [], //所有角色列表
                    roleIdList: [], // 选中的角色id列表
                    isIndeterminate: false, // 全选时的中间状态
                }

            }
        },
        methods: {
            // 切换页码时触发
            handleCurrentChange(page) {
                this.page = page
                this.getUserList()
            },
            // 当前页面显示数据条数改变时触发
            handleSizeChange(limit) {
                this.limit = limit
                this.getUserList()
            },
            // 点击上一页
            handlePrevClick(page) {
                this.page = page
                this.getUserList()
            },
            // 点击下一页
            handleNextClick(page) {
                this.page = page
                this.getUserList()
            },
            // 获取用户分页列表数据
            async getUserList() {
                this.listLoading = true // 显示加载动画
                const { page, limit, searchObj } = this
                const result = await this.$api.user.reqGetUserList(page, limit, searchObj)
                if (result.code == 20000) {
                    this.total = result.data.total
                    this.userList = result.data.items
                    this.listLoading = false // 关闭加载动画
                }
            },
            // 搜索用户
            search() {
                if (this.searchObj.username || this.searchObj.nickName) { // 当输入框收集数据不为空时
                    this.getUserList()
                }
            },
            // 清空搜索内容
            clear() {
                this.searchObj.username = '' // 将用户名输入框清空
                this.searchObj.nickName = '' // 将昵称输入框清空
                this.getUserList() // 重新获取用户列表
            },
            // 添加用户
            addUser() {
                this.user = {} // 清空用户信息
                this.addUserDialogVisible = true // 显示添加用户弹框
                this.isAdd = true // 显示添加用户弹框
            },
            // 修改用户
            async editUser(row) {
                this.addUserDialogVisible = true // 显示添加用户弹框
                this.isAdd = false // 显示修改用户弹框
                const result = await this.$api.user.reqGetuser(row.id)
                if (result.code == 20000) {
                    this.user = result.data.item // 获取用户信息并展示
                }
            },
            // 确认添加/修改用户
            confirmAddOrAditUser() {
                // 通过ref获取当前表单，验证通过再进入逻辑判断
                this.$refs.ruleForm.validate(async (valid) => {
                    if (valid) {
                        if (this.isAdd) { // 当前为添加弹框
                            this.$message({
                                type: 'success',
                                message: '添加成功！'
                            })
                            this.addUserDialogVisible = false // 隐藏添加用户弹框

                            // 收集表单数据提交到服务器
                            const result = await this.$api.user.reqAddUser(this.user)
                            if (result.code == 20000) { // 添加成功
                                this.getUserList() //重新获取分页数据
                            } else {
                                this.$message.error('添加失败！');
                            }
                        } else { // 当前为修改弹框
                            this.$message({
                                type: 'success',
                                message: '修改成功！'
                            })
                            this.addUserDialogVisible = false // 隐藏添加用户弹框

                            // 收集表单数据提交到服务器
                            const result = await this.$api.user.reqUpdataUser(this.user)
                            if (result.code == 20000) { // 修改成功
                                this.getUserList() //重新获取分页数据
                            } else {
                                this.$message.error('修改失败！');
                            }
                        }

                    }
                })
            },
            // 删除用户
            async deleteUser(row) {
                const result = await this.$api.user.reqDeleteUser(row.id)
                if (result.code == 20000) { // 删除成功
                    this.getUserList() // 重新获取用户分页列表
                }
            },
            // 获取选中的用户id列表 | 通过@selection-change事件可以获取当前选中的对象列表
            handleSelectionChange(selection) {
                const idList = []
                selection.forEach(item => {// 遍历数组
                    idList.push(item.id) // 收集数组中每条元素的id并push到idList中
                });
                this.userIdList = [...idList] // 通过浅拷贝收集选中元素的id
            },
            // 删除选中 
            async deleteChecked() {
                this.$confirm('此操作将永久删除选中的用户, 是否继续?', '批量删除', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(async () => {
                    this.$message({
                        type: 'success',
                        message: '删除成功!'
                    });
                    const result = await this.$api.user.reqDeleteUserList(this.userIdList)
                    if (result.code == 20000) { // 删除成功
                        this.getUserList() // 重新获取用户分页列表
                    }
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                });
            },
            // 设置角色
            async assignRole(row) {
                this.roleDialogVisible = true // 显示设置角色弹框
                this.roleForm.username = row.username // 展示用户名
                this.roleForm.userId = row.id // 收集用户id
                this.roleForm.roleIdList = [] // 清空选中角色数据 | 防止未设置角色退出弹框时，选中的角色数据残留造成显示错误

                const result = await this.$api.user.reqGetRole(row.id)
                if (result.code == 20000) { //请求成功
                    this.roleForm.allRolesList = result.data.allRolesList // 获取所有角色列表
                    result.data.assignRoles.forEach(item => {
                        this.roleForm.roleIdList.push(item.id)
                    })
                }
            },
            // 切换全选框时
            handleCheckAllChange(value) {
                if (value) { // 全选
                    const idList = [] // 声明一个空数组
                    this.roleForm.allRolesList.forEach(item => { // 遍历全部角色
                        idList.push(item.id) // 收集全部角色的id
                    })
                    this.roleForm.roleIdList = idList // 全选角色
                } else { //全不选
                    this.roleForm.roleIdList = [] // 全不选角色
                }
                this.roleForm.isIndeterminate = false // 全选时的中间状态
            },
            // 点击单个复选框时
            handleCheckedRoleChange(value) {
                let checkedCount = value.length // 获取当前选中的数组长度
                // 点击单个元素时用到，全部点完全选显示，反则不显示
                this.roleForm.checkAll = checkedCount === this.roleForm.allRolesList.length // 当前选中的长度 === 全部角色数组总长度 | true:全选 / false:全不选
                // 选择了元素但未全部选中时，全选框显示中间状态
                this.roleForm.isIndeterminate = checkedCount > 0 && checkedCount < this.roleForm.allRolesList.length // 当前选中长度 > 0 且 < 全部角色数组总长度 | 全部满足为真/反之为假
            },
            // 设置角色确认按钮
            async confirmAssignRole() {
                // 整理参数
                const data = {
                    userId: this.roleForm.userId, // 用户id
                    // params参数不能直接传递数组，需要将数组转成字符串的方式传输过去
                    roleId: `${this.roleForm.roleIdList}` // 角色id列表 
                }
                const result = await this.$api.user.reqDoAssign(data)
                if (result.code == 20000) { // 请求成功
                    this.roleDialogVisible = false // 隐藏设置角色弹框
                    this.getUserList() // 重新获取分页列表
                    this.$message({
                        type: 'success',
                        message: '设置成功！'
                    })
                } else {
                    this.$message.error('设置失败！')
                }
            },
        },
    }
</script>
<style scoped>
    .user-list {
        margin-top: 30px;
    }
</style>